﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
using System;

public class DraggableItemCallBack
{
    public Action OnBeginDrag;
    public Action OnDragging;
    public Action<GameObject> OnEndDrag;
    public Action OnMoveBackComplete;
}

[RequireComponent(typeof(DragIdentify))]
public abstract class UIDragBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public enum DragMode { None,Scroll,Drag}   //无操作，滚动，拖拽
    public bool _isScrollItem = false;      //本拖拽物体是否属于scrollrect的目标
    public float _scrollSensitity = -1f;
    public bool _isPlayBackAudio = true;

    public ScrollRectHelper _scrollrect;
    public bool _isAutoBack;
    public float _tweenduration = 0.5f;
    public bool _userAgent;
    protected RectTransform _currentDragAgent;
    private DraggableItemCallBack _callback;

    protected DragMode _currentDragMode;
    protected bool _isOnTweening;
    protected bool _isOnDragging;
    protected RectTransform _rt;
    protected Color _invisible = new Color(1,1,1,1f / 256);
    protected DragIdentify _identyself;
    Vector3 _dragStartAnchorPosition;
    protected Vector3 _lastMousePostion;
    

    private  void Awake()
    {
        _rt = GetComponent<RectTransform>();
        _identyself = GetComponentInChildren<DragIdentify>();
        ResetStartDragPosition();
        InitComponet();
        _scrollrect = transform.GetComponentInParent<ScrollRectHelper>();
    }

    public virtual void InitComponet() { }

    public virtual void Update() {
        if (_isOnDragging)
        {
            DragOperationApply(_currentDragAgent);
        }
    }

    GameObject clone;
    public virtual void OnBeginDrag(PointerEventData eventData)
    {
        //每次拖拽开始，将DragComparerManager的上次匹配的目标清空
        DragComparerManager.Instance._current_dragIdentify = null;
        //触发一次拖拽开始的事件
        HospitalEventHandler.Instance.BroadCastEvent<DragIdentify>(HospitalEventID.DRAG_BEGIN, _identyself);

        //Debug.Log("delta: " + eventData.delta + " scrolldelta: " + eventData.scrollDelta);
        _lastMousePostion = Input.mousePosition;
        Vector2 move_delta = eventData.delta;
        _currentDragMode = Mathf.Abs(move_delta.y) >= Mathf.Abs(move_delta.x) && _isScrollItem ? DragMode.Scroll : DragMode.Drag;

        //如果使用拖拽代理的方式，拖拽开始时，隐藏原来的，而移动代理的位置来产生拖拽的效果
        if (_userAgent)
        {
            _isOnDragging = true;

            if (_currentDragMode == DragMode.Drag)
            {
                //设置拖拽代理
                _currentDragAgent = DragComparerManager.Instance._currentDragAgent;
                _currentDragAgent.GetComponent<Graphic>().raycastTarget = false;
                _currentDragAgent.GetComponent<Graphic>().color = _invisible;
                _currentDragAgent.SetActive(true);

                //克隆出拖拽对象
                clone = Instantiate<GameObject>(gameObject);
                clone.transform.SetParent(_currentDragAgent);
                clone.transform.SetTransformFormTarget(_currentDragAgent);
                SetRaycastTarget(clone.transform, false);

                //记录拖拽代理的ui起始位置
                _dragStartAnchorPosition = UGUITweener.GetCanvasAnchorLocalPosition(WindowManager.Instance.canvas, _rt);


                //关闭原始元素的显示
                SetGraphicsVisble(_rt, false);
            }
        }
        else
        {
            if (_currentDragMode == DragMode.Drag)
            {
                SetRaycastTarget(_rt, false);
            }
        }

    }

    public virtual void OnDrag(PointerEventData eventData)
    {
        if (!_userAgent)
        {
            DragOperationApply(_rt);
        }

        HospitalEventHandler.Instance.BroadCastEvent<DragIdentify>(HospitalEventID.DRAGGING, _identyself);
    }

    Vector2 dragdelta;
    private void DragOperationApply(RectTransform applytarget)
    {
        dragdelta =(Input.mousePosition - _lastMousePostion);
        
        if (_currentDragMode == DragMode.Scroll)
        {
            _scrollrect._scrooldelta = dragdelta;
            _lastMousePostion = Input.mousePosition;
        }
        else if (_currentDragMode == DragMode.Drag)
        {
            Vector2 rectPos;
            if (UGUITweener.GetRectPosForScreenPos(WindowManager.Instance.canvas, Input.mousePosition, out rectPos))
            {
                applytarget.anchoredPosition = rectPos;
            }
        }
    }

    public virtual void OnEndDrag(PointerEventData eventData)
    {
        if (_currentDragMode == DragMode.Drag)
        {
            if (_userAgent)
            {
                _isOnDragging = false;
            }

            if (this._callback != null && this._callback.OnEndDrag != null) this._callback.OnEndDrag(gameObject);

            //拖拽结束后，触发一个匹配事件
            HospitalEventHandler.Instance.BroadCastEvent<DragIdentify>(HospitalEventID.DRAG_MATCH, _identyself);

            if (_isAutoBack)
            {
                if (_userAgent)
                {
                    if (!DragComparerManager.Instance.IsMatch(this._identyself))
                    {
                        if (_isPlayBackAudio) HospitalUtil.PlayAudio(HospitalConsts.audio_zidonghuigui);
                        //如果匹配不成功，则药片需要回复到原位
                        _isOnTweening = true;
                        _currentDragAgent.DOAnchorPos(_dragStartAnchorPosition, _tweenduration).OnComplete(() =>
                        {
                            if (this._callback != null && this._callback.OnMoveBackComplete != null) this._callback.OnMoveBackComplete();
                            _isOnTweening = false;
                            Destroy(clone);
                            _currentDragAgent.SetActive(false);
                            SetGraphicsVisble(_rt, true);
                            SetRaycastTarget(_rt, true);
                        });
                    }
                    else
                    {   //匹配成功，直接隐藏代理
                        SetRaycastTarget(_rt, true);
                        Destroy(clone);
                        _currentDragAgent.SetActive(false);
                    }
                }
                else
                {
                    if (_isPlayBackAudio) HospitalUtil.PlayAudio(HospitalConsts.audio_zidonghuigui);
                    _rt.DOAnchorPos(_dragStartAnchorPosition, _tweenduration).OnComplete(() =>
                    {
                        if (this._callback != null && this._callback.OnMoveBackComplete != null) this._callback.OnMoveBackComplete();
                        _isOnTweening = false;
                        SetRaycastTarget(_rt, true);
                    });
                }

            }
            else
            {
                SetRaycastTarget(_rt, true);
            }

        }

        _currentDragMode = DragMode.None;
    }

    public virtual void SetRaycastTarget(Transform target, bool isEnable)
    {
        Graphic[] raycastuis = target.GetComponentsInChildren<Graphic>();
        for (int i = 0; i < raycastuis.Length; i++)
            raycastuis[i].raycastTarget = isEnable;
    }

    public virtual void SetGraphicsVisble(Transform target, bool isshow)
    {
        Graphic[] raycastuis = target.GetComponentsInChildren<Graphic>();
        for (int i = 0; i < raycastuis.Length; i++)
            raycastuis[i].enabled = isshow;
        
        //隐藏了graphic组件后再显示时，layout的排序功能会异常，所以这里强制对layoutgroup进行排序
        if(isshow) LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
    }

    public void SetToDragStartPostion()
    {
        _rt.anchoredPosition = _dragStartAnchorPosition;
    }

    public void ResetStartDragPosition()
    {
        if (_userAgent)
        {

        }
        else
        {
            _dragStartAnchorPosition = _rt.anchoredPosition;
        }
    }
}
